<template>
    <div class="server-info">
        <div class="alert">
            <el-alert :closable="false" :show-icon="true" type="success">
                数据获取时间 {{ datetime }}
                <a style="position: absolute; right: 35px; cursor: pointer" @click="onRefresh">点击刷新</a>
            </el-alert>
        </div>

        <el-card :body-style="{ padding: '10px' }" shadow="hover">
            <div id="cpuUsage" class="chart-box"></div>
        </el-card>

        <el-table :data="dataSource" style="margin-top: 5px">
            <el-table-column label="参数" prop="name"></el-table-column>
            <el-table-column label="描述" prop="description"></el-table-column>
            <el-table-column label="当前值" prop="value"></el-table-column>
        </el-table>
    </div>
</template>
<script>
import axios from 'axios';
import {service, dateFormat} from "@/utils";
import * as echarts from 'echarts';
import {defineComponent, getCurrentInstance, onActivated, onBeforeMount, onBeforeUnmount, onDeactivated, onMounted, reactive, ref} from 'vue';

export default defineComponent({
    name: 'MonitorServer',
    setup() {
        const {proxy} = getCurrentInstance();
        const dataSource = ref([]);
        const datetime = ref([]);
        const cpuUsage = reactive({
            instance: null,
            data: [],
            xdata: [],
            option: {
                title: {
                    text: 'CPU使用率'
                },
                tooltip: {
                    trigger: 'axis',
                    formatter: function (params) {
                        return params[0].value;
                    },
                    axisPointer: {
                        animation: true,
                        type: 'cross'
                    }
                },
                xAxis: {
                    type: 'category',
                    splitLine: {
                        show: false
                    },
                    data: null
                },
                yAxis: {
                    type: 'value',
                    boundaryGap: [0, '100%'],
                    splitLine: {
                        show: false
                    },
                    axisLabel: {
                        formatter: '{value} %'
                    },
                    axisPointer: {
                        snap: true
                    }
                },
                dataZoom: [
                    {
                        type: 'inside',
                        start: 0,
                        end: 30
                    },
                    {
                        start: 0,
                        end: 30
                    }
                ],
                series: [{
                    name: '模拟数据',
                    type: 'line',
                    showSymbol: false,
                    smooth: false,
                    itemStyle: {
                        color: 'rgb(255, 70, 131)'
                    },
                    data: []
                }]
            }
        });

        const toPercentage = (value) => {
            return Number(value * 100).toFixed(2);
        };
        const toDateTime = (time) => {
            let date = new Date(time * 1000); // 时间戳为10位需*1000，时间戳为13位的话不需乘1000
            let Y = date.getFullYear() + '-';
            let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
            let D = date.getDate() + ' ';
            let h = date.getHours() + ':';
            let m = date.getMinutes() + ':';
            let s = date.getSeconds();
            return Y + M + D + h + m + s;
        };
        const toTime = (time) => {
            let val = time + '秒';
            if ((time = time / 60) < 60) {
                val = Number(time).toFixed(2) + '分钟';
            } else if ((time = time / 60) < 24) {
                val = Number(time).toFixed(2) + '小时';
            } else {
                val = Number(time / 24).toFixed(2) + '天';
            }
            return val;
        };
        const desc = reactive({
            'system.cpu.count': {desc: 'CPU数量', unit: '核'},
            'system.cpu.usage': {desc: '系统CPU使用率', unit: '%', convert: toPercentage},
            'process.start.time': {desc: '后台启动时间点', convert: toDateTime},
            'process.uptime': {desc: '后台已运行时间', convert: toTime},
            'process.cpu.usage': {desc: '当前进程CPU使用率', unit: '%'}
        });

        let interval = null;
        let isActive = false;
        const initEchartsHandle = () => {
            if (isActive) return;
            isActive = true;
            let minMemory = 1e10;
            let maxMemory = -1e10;
            interval = setInterval(() => {
                axios.all([service.get('/actuator/metrics/system.cpu.usage')]).then((r) => {
                    let currentMemory = r[0].measurements[0].value * 100;
                    if (currentMemory < minMemory) minMemory = currentMemory;
                    if (currentMemory > maxMemory) maxMemory = currentMemory;
                    let time = dateFormat(new Date(), 'mm:ss');
                    cpuUsage.data.push(currentMemory);
                    cpuUsage.xdata.push(time);
                    if (cpuUsage.data.length >= 300) {
                        cpuUsage.data.shift();
                        cpuUsage.xdata.shift();
                    }

                    cpuUsage.instance.setOption({
                        series: [{
                            data: cpuUsage.data
                        }],
                        xAxis: {
                            data: cpuUsage.xdata
                        }
                    });

                }).catch((r) => {
                    console.error(r);
                    stop();
                });
            }, 1000);
        };

        const onRefresh = () => {
            let date = new Date();
            datetime.value = date.getFullYear() + '年' + date.getMonth() + '月' + date.getDay() + '日' +
                    date.getHours() + '时' + date.getMinutes() + '分' + date.getSeconds() + '秒';
            axios.all([
                service.get('/actuator/metrics/system.cpu.count'),
                service.get('/actuator/metrics/system.cpu.usage'),
                service.get('/actuator/metrics/process.uptime'),
                service.get('/actuator/metrics/process.start.time'),
                service.get('/actuator/metrics/process.cpu.usage')
            ]).then((r) => {
                dataSource.value = [];
                r.forEach(item => {
                    for (let i = 0; i < item.measurements.length; i++) {
                        let obj = {};
                        let measurement = item.measurements[i];
                        obj.name = measurement.statistic === 'VALUE' ? item.name : item.name + '.' + measurement.statistic.toLowerCase().toCamelCase();
                        let dc = desc[obj.name];
                        obj.value = (dc.convert ? dc.convert(measurement.value) : measurement.value) + (dc.unit || '');
                        obj.description = dc.desc;
                        dataSource.value.push(obj);
                    }
                });
            }).catch((r) => {
                console.error(r);
                proxy.$message.error('获取服务器信息失败');
            });
        };

        const stop = () => {
            if (interval) {
                clearInterval(interval);
                isActive = false;
                interval = null;
            }
        };

        onBeforeMount(() => onRefresh())

        onMounted(() => {
            cpuUsage.instance = echarts.init(document.getElementById('cpuUsage'));
            cpuUsage.instance.setOption(cpuUsage.option);
            initEchartsHandle();
        });

        onBeforeUnmount(() => stop());

        onActivated(() => initEchartsHandle())

        onDeactivated(() => stop())
        return {
            datetime, dataSource,
            onRefresh
        };
    }
});
</script>
<style lang="scss" scoped>
.server-info {
    width: 100%;


    .chart-box {
        min-height: 40vh;
    }
}
</style>
